package com.example.lambda.test4;

import org.junit.Test;

import java.util.Comparator;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * @author readpage
 * @create 2022-10-22 13:20
 *
 * 方法引用的使用
 * 1.使用情境: 当要传递给Lambda体的操作，以经有实现的方法了，可以使用方法引用!
 *
 * 2.方法引用，本质上就是Lambda表达式,而Lambda表达式作为函数接口的实例。所以
 *   方法引用，也是函数式接口的实例。
 *
 * 3. 使用格式: 类(或对象) :: 方法名
 *
 * 4. 具体分为如下的三种情况:
 *    情况1   对象 :: 非静态方法
 *    情况2   类 :: 静态方法
 *
 *    情况3   类 :: 非静态方法
 *
 *
 * 5. 方法引用使用的要求: 要求接口中的抽象方法的形参列表和返回值类型与方法引用的方法的
 *      形参列表和返回值类型相同!
 *
 */
public class MethodRefTest {
    //情况一: 对象 :: 实例方法
    //Consumer中的void Accept(T t)
    //PrintStream中的void println(T t)
    @Test
    public void test() {
        Consumer<String> consumer = s -> System.out.println(s);
        consumer.accept("hello world!");
        System.out.println("**********************");
        Consumer<String> con2 = System.out::println;
    }

    //Supplier中的 T get()
    //Employee中多个String getName()
    @Test
    public void test2() {
        Employee emp = new Employee(1011, "Tom", 23, 5600);
        Supplier<String> supplier = () -> emp.getName();
        System.out.println(supplier.get());
        System.out.println("*******************");
        Supplier<String> supplier2 = emp::getName;
        System.out.println(supplier2.get());
    }

    //情况而: 类 :: 静态方法
    //Comparator中的int compare(T t1, T t2)
    //Integer中的int compare(T t1, T t2)
    @Test
    public void test3() {
        Comparator<Integer> com = (o1, o2) -> Integer.compare(o1, o2);
        com.compare(12, 21);
        System.out.println("***************");
        Comparator<Integer> com2 = Integer::compare;
        System.out.println(com2.compare(12, 3));
    }

    //Function中的R apply(T t)
    //Math中的Long round(Double d)
    @Test
    public void test4() {
        Function<Double, Long> func = aDouble -> Math.round(aDouble);
        System.out.println(func.apply(12.3));
        System.out.println("********************");
        Function<Double, Long> func2 = Math::round;
        System.out.println(func2.apply(12.6));
    }

    // 情况三: 类 :: 实例方法
    // Comparator中的int compare(T t1, T t2)
    // String中的int t1.compareTo(t2)
    @Test
    public void test5() {
        Comparator<String> com = (o1, o2) -> o1.compareTo(o2);
        System.out.println(com.compare("abc", "abd"));
        System.out.println("***************");
        Comparator<String> com2 = String::compareTo;
        System.out.println(com2.compare("abd", "abm"));
    }

    //BiPredicate中的boolean test(T t1, T t2);
    //String中的boolean t1.equals(t2)
    @Test
    public void test6() {
        BiPredicate<String, String> pre = (s, s2) -> s.equals(s2);
        System.out.println(pre.test("abc", "abc"));
        System.out.println("************");
        BiPredicate<String, String> pre2 = String::equals;
        System.out.println(pre.test("abc", "abd"));
    }

    //Function中的R apply(T t)
    //Employee中的String getName();
    @Test
    public void test7() {
        Employee employee = new Employee(1001, "Jerry", 23, 6000);
        Function<Employee, String> func = e -> e.getName();
        System.out.println(func.apply(employee));

        System.out.println("**************");

        Function<Employee, String> func2 = Employee::getName;
        System.out.println(func2.apply(employee));
    }
}
